/**
 * @file logging.h
 * @author SDK_TEAM
 * @brief
 * @version 0.1
 * @date 2022-11-09
 *
 * Copyright:
 * © 2018 北京灵汐科技有限公司 版权所有。
 * 注意：以下内容均为北京灵汐科技有限公司原创，未经本公司允许，不得转载，否则将视为侵权；对于不遵守此声明或者其他违法使用以下内容者，本公司依法保留追究权。
 * © 2018 Lynxi Technologies Co., Ltd. All rights reserved.
 * NOTICE: All information contained here is, and remains the property of Lynxi.
 * This file can not be copied or distributed without the permission of Lynxi
 * Technologies Co., Ltd.
 *
 */
#ifndef __LOGING_HPP__
#define __LOGING_HPP__

#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>

#define unuse(x) ((x) = (x))
#define LOG_TIME_SIZE (128)

#define DEBUG (1)
#define PRINT_FULL_FUNCTION_NAME (0)
#define PRINT_THREAD_PROCESS_ID_AND_FULL_TIME (0)

#if PRINT_FULL_FUNCTION_NAME
#define FUNC_FORMAT __PRETTY_FUNCTION__
#else
#define FUNC_FORMAT __func__
#endif

// Print only file names (filter out directories)
#define FILE_NAME(x) (strrchr((x), '/') ? strrchr((x), '/') + 1 : (x))

static char logTime[LOG_TIME_SIZE] = {0};

static void getTimeStr(char *t) {
  struct timeval tv;
  struct timezone tz;
  struct tm *p;

  gettimeofday(&tv, &tz);
  p = localtime(&tv.tv_sec);
#if (PRINT_THREAD_PROCESS_ID_AND_FULL_TIME)
  snprintf(t, LOG_TIME_SIZE, "%04d/%02d/%02d %02d:%02d:%02d.%06ld %6d %6ld",
           p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min,
           p->tm_sec, tv.tv_usec, getpid(), syscall(SYS_gettid));
#else
  snprintf(t, LOG_TIME_SIZE, "%04d/%02d/%02d %02d:%02d:%02d.%06ld",
           p->tm_year + 1900, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min,
           p->tm_sec, tv.tv_usec);
#endif
}

#if (DEBUG)
#define logi(format, ...)                                         \
  getTimeStr(logTime);                                            \
  fprintf(stdout, "\033[1m\033[40;37m %s I [%s:%s:%d] ", logTime, \
          FILE_NAME(__FILE__), FUNC_FORMAT, __LINE__);            \
  fprintf(stdout, format, ##__VA_ARGS__);                         \
  fprintf(stdout, "\033[0m\n");

#define logd(format, ...)                                         \
  getTimeStr(logTime);                                            \
  fprintf(stdout, "\033[1m\033[40;32m %s D [%s:%s:%d] ", logTime, \
          FILE_NAME(__FILE__), FUNC_FORMAT, __LINE__);            \
  fprintf(stdout, format, ##__VA_ARGS__);                         \
  fprintf(stdout, "\033[0m\n");

#define logw(format, ...)                                         \
  getTimeStr(logTime);                                            \
  fprintf(stdout, "\033[1m\033[40;33m %s W [%s:%s:%d] ", logTime, \
          FILE_NAME(__FILE__), FUNC_FORMAT, __LINE__);            \
  fprintf(stdout, format, ##__VA_ARGS__);                         \
  fprintf(stdout, "\033[0m\n");

#define loge(format, arg...)                                      \
  getTimeStr(logTime);                                            \
  fprintf(stdout, "\033[1m\033[40;31m %s E [%s:%s:%d] ", logTime, \
          FILE_NAME(__FILE__), FUNC_FORMAT, __LINE__);            \
  fprintf(stdout, format, ##arg);                                 \
  fprintf(stdout, "\033[0m\n");

#define logmark(format, arg...)                                   \
  getTimeStr(logTime);                                            \
  fprintf(stdout, "\033[1m\033[40;35m %s M [%s:%s:%d] ", logTime, \
          FILE_NAME(__FILE__), FUNC_FORMAT, __LINE__);            \
  fprintf(stdout, format, ##arg);                                 \
  fprintf(stdout, "\033[0m \n");

#define login() logi("IN")

#define logout() logi("OUT")

#else
#define logi(format, ...)
#define logd(format, ...)
#define logw(format, ...)
#define loge(format, ...)
#define logmark(format, ...)
#define login(format, ...)
#define logout(format, ...)

#endif  // end DEBUG

#endif  // end __JINBO_LOG_H__
